package com.bill99.testmp.framework.helper;

import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;

import org.springframework.util.StringUtils;

import com.bill99.testmp.testmanage.common.schema.Class;
import com.bill99.testmp.testmanage.common.schema.Classes;
import com.bill99.testmp.testmanage.common.schema.Include;
import com.bill99.testmp.testmanage.common.schema.Methods;
import com.bill99.testmp.testmanage.common.schema.ObjectFactory;
import com.bill99.testmp.testmanage.common.schema.Suite;
import com.bill99.testmp.testmanage.orm.ibatis.dto.JinkensJobMethodDto;
import com.bill99.testmp.testmanage.orm.manager.TaMng;

public class JenkinsSchemaHelper {

	public static String parseJenkinsJobXml(String jobName, List<JinkensJobMethodDto> jinkensJobMethodDtos, TaMng taMng) {
		String jenkinsJobXmlStr = "";
		Map<String, List<JinkensJobMethodDto>> jenkinsJobMap = new HashMap<String, List<JinkensJobMethodDto>>();

		List<JinkensJobMethodDto> jinkensJobMethodDtoTmps = null;
		for (JinkensJobMethodDto jinkensJobMethodDto : jinkensJobMethodDtos) {
			if (jenkinsJobMap.get(jinkensJobMethodDto.getClassName()) != null) {
				jinkensJobMethodDtoTmps = jenkinsJobMap.get(jinkensJobMethodDto.getClassName());
			} else {
				jinkensJobMethodDtoTmps = new ArrayList<JinkensJobMethodDto>();
			}
			jinkensJobMethodDtoTmps.add(jinkensJobMethodDto);
			jenkinsJobMap.put(jinkensJobMethodDto.getClassName(), jinkensJobMethodDtoTmps);
		}

		if (jenkinsJobMap.size() > 0) {

			try {
				JAXBContext jc = JAXBContext.newInstance("com.bill99.testmp.testmanage.common.schema"); //参数为JAXB生成的java文件所在包名
				ObjectFactory objFactory = new ObjectFactory(); //生成对象工厂

				List<Include> includes = null;
				List<Class> clazzs = new ArrayList<Class>();
				List<Methods> methods = null;
				for (Entry<String, List<JinkensJobMethodDto>> entry : jenkinsJobMap.entrySet()) {
					String className = entry.getKey();
					List<JinkensJobMethodDto> includeMethods = entry.getValue();

					methods = new ArrayList<Methods>();
					includes = new ArrayList<Include>();

					for (JinkensJobMethodDto includeMethod : includeMethods) {
						Include include = new Include();//Include
						include.setName(includeMethod.getMethodName());

						//						if (StringUtils.hasLength(includeMethod.getDependsOnMethods())) {
						//							String[] dependsOnMethods = includeMethod.getDependsOnMethods().split(",");
						//							for (String dependsOnMethod : dependsOnMethods) {
						//								Include includeDm = new Include();//Include
						//								includeDm.setName(dependsOnMethod.trim());
						//								includes.add(includeDm);
						//							}
						//						}

						includes.addAll(initDependsOnMethods(includeMethod, taMng));

						includes.add(include);
					}

					Methods method = new Methods();//Methods
					method.setInclude(uniq(includes));
					methods.add(method);

					Class clazz = new Class();
					clazz.setName(className);
					clazz.setMethods(methods);
					clazzs.add(clazz);

				}

				Classes classe = new Classes();
				classe.setClazz(clazzs);

				com.bill99.testmp.testmanage.common.schema.Test test = new com.bill99.testmp.testmanage.common.schema.Test();
				test.setClasses(classe);
				test.setName(jobName);

				Suite suite = objFactory.createSuite();
				suite.setName(jobName);
				ArrayList<com.bill99.testmp.testmanage.common.schema.Test> tests = new ArrayList<com.bill99.testmp.testmanage.common.schema.Test>();
				tests.add(test);
				suite.setTest(tests);

				Marshaller marshaller = jc.createMarshaller();
				marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);

				OutputStream bos = new ByteArrayOutputStream();
				marshaller.marshal(suite, bos);
				jenkinsJobXmlStr = bos.toString();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return jenkinsJobXmlStr;
	}

	private static List<Include> initDependsOnMethods(JinkensJobMethodDto includeMethod, TaMng taMng) {

		List<Include> includes = new ArrayList<Include>();

		if (StringUtils.hasLength(includeMethod.getDependsOnMethods())) {
			String[] dependsOnMethods = includeMethod.getDependsOnMethods().split(",");
			for (String dependsOnMethod : dependsOnMethods) {
				Include includeDm = new Include();//Include
				includeDm.setName(dependsOnMethod.trim());
				includes.add(includeDm);
				includeMethod.setMethodName(dependsOnMethod);
				includes.addAll(initDependsOnMethods(taMng.getJinkensJobMethodsByName(includeMethod), taMng));
			}

		}
		return includes;
	}

	private static List<Include> uniq(List<Include> includes) {
		List<Include> includeTmps = new ArrayList<Include>();
		Set<String> includeSets = new HashSet<String>();
		if (includes != null && includes.size() > 0) {
			for (Include include : includes) {
				includeSets.add(include.getName());
			}
			for (String string : includeSets) {
				Include include = new Include();
				include.setName(string);
				includeTmps.add(include);
			}
		}
		return includeTmps;
	}
}
